/*!
 * \file cmd_queue.h
 * \brief 串口指令队列（支持多队列、多帧头、可配置帧长）
 * \version 1.3
 * \date 2024.10
 * \copyright wo4fisher
 */

#ifndef _CMD_QUEUE
#define _CMD_QUEUE
#include "ti_msp_dl_config.h"

// 队列配置参数
#define QUEUE_MAX_SIZE 100

typedef uint8_t qdata;
typedef uint16_t qsize;

// 接收状态结构体
typedef struct {
  uint8_t pos;        // 当前接收位置
  const qdata *pHead; // 帧头指针
  uint8_t head_len;   // 帧头长度
  uint8_t frame_len;  // 总帧长（含帧头）
} CmdState;

// 队列句柄结构体定义
typedef struct {
  qsize _head;                 // 写指针
  qsize _tail;                 // 读指针
  qdata _data[QUEUE_MAX_SIZE]; // 数据缓冲区
} QueueHandle;

/*!
 * \brief 初始化一个新的队列
 * \param[out] q 指向队列句柄的指针
 */
void queue_init(QueueHandle *q);

/*!
 * \brief 清空指定队列
 * \param[in] q 队列句柄
 */
void queue_reset(QueueHandle *q);

/*!
 * \brief 将字节加入队列
 * \param[in] q 队列句柄
 * \param[in] _data 要入队的数据
 */
void queue_push(QueueHandle *q, qdata _data);

/*!
 * \brief 从队列中取出一个字节
 * \param[in] q 队列句柄
 * \param[out] _data 数据输出指针
 * \return 成功返回 true，队列为空返回 false
 */
uint8_t queue_pop(QueueHandle *q, qdata *_data);

/*!
 * \brief 获取队列中当前有效数据个数
 * \param[in] q 队列句柄
 * \return 当前未读取的数据数量
 */
qsize queue_size(QueueHandle *q);

/*!
 * \brief 从队列中提取一条完整指令帧（支持多帧头、帧长可配）
 * \param[in] q 队列句柄
 * \param[out] buffer 接收缓冲区
 * \param[in] buf_len 缓冲区大小
 * \param[in] frame_header 帧头数组（如 {0x3F, 0x06}）
 * \param[in] header_len 帧头长度
 * \param[in] total_frame_len 完整帧长度（含帧头）
 * \return 成功接收的字节数，0 表示无完整帧
 */
qsize queue_find_cmd_ext(QueueHandle *q, qdata *buffer, qsize buf_len,
                         const qdata *frame_header, uint8_t header_len,
                         uint8_t total_frame_len);

#endif // _CMD_QUEUE
